#ifndef BASE_H
#define BASE_H

#include "config.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

typedef float mat3[3][3];
typedef float vec2[2];

//
// Time
//

/**
 * \brief Get time since module initialization.
 * \return Time, in seconds.
 */
float time_get(void);

/**
 * \brief Suspend execution for a duration.
 * \param secs Delay, in seconds.
 */
void time_sleep(float secs);

//
// Matrix
//

/**
 * \brief Initialize a 3x3 identity matrix.
 * \param m Matrix.
 */
void mat3_identity(mat3 m);

/**
 * \brief Duplicate a 3x3 matrix.
 * \param src Source matrix.
 * \param dest Destination matrix.
 */
void mat3_copy(mat3 dest, mat3 src);


/**
 * \brief Multiply a matrix with a translation.
 * \param m Destination matrix.
 * \param t Translation vector.
 */
void mat3_translate(mat3 m, vec2 t);

/**
 * \brief Multiply a matrix with a scale.
 * \param m Destination matrix.
 * \param t Scale vector.
 */
void mat3_scale(mat3 m, vec2 s);

/**
 * \brief Multiply a matrix with a rotation.
 * \param m Destination matrix.
 * \param t Angle, in degrees.
 */
void mat3_rotate(mat3 m, float angle);

/**
 * \brief Multiply two matrices.
 * \param dest Result matrix.
 * \param m1 First source matrix.
 * \param m2 Second source matrix.
 */
void mat3_mult(mat3 dest, mat3 m1, mat3 m2);

/**
 * \brief Multiply a matrix and a vector.
 * \param dest Result vector.
 * \param m1 Source matrix.
 * \param m2 Source vector.
 */
void mat3_mult_vec(vec2 dest, mat3 m, vec2 v);

/**
 * \brief Print a matrix to a FILE stream.
 * \param m Matrix to print.
 * \param f FILE stream.
 */
void mat3_print(mat3 m, FILE *f);

//
// Vector
//

/**
 * \brief Compute the dot product of two vectors.
 * \param u First vector.
 * \param v Second vector.
 * \return The dot product.
 */
float vec2_dot(vec2 u, vec2 v);

/**
 * \brief Compute the length of a vector.
 * \param u First vector.
 * \param v Second vector.
 * \return The dot product.
 */
float vec2_length(vec2 u);

/**
 * \brief Substract two vectors.
 * \param dest Result vector.
 * \param u First vector.
 * \param v Second vector.
 */
void vec2_sub(vec2 dest, vec2 u, vec2 v);

/**
 * \brief Multiply a vector by a scalar.
 * \param dest Result vector.
 * \param u Vector.
 * \param k Scalar.
 */
void vec2_mult(vec2 dest, vec2 u, float k);

/**
 * \brief Print a vector to a FILE stream.
 * \param v Vector to print.
 * \param f FILE stream.
 */
void vec2_print(vec2 v, FILE *f);

//
// Initialization
//

void base_init(void);
void base_exit(void);

#endif

